﻿package core.ui.util
{
    import core.enum.*;
    import core.image.*;
    import core.ui.controls.*;
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    public class CropTool extends Sprite
    {
        var ed:Tuyitu;
        var raster:Sprite;
        var options:Object;
        var tw:int;
        var th:int;
        var ax:int;
        var ay:int;
        var shifted:Boolean;
        var croprect:Rectangle;
        var topleft:Sprite;
        var topright:Sprite;
        var bottomleft:Sprite;
        var bottomright:Sprite;
        var xpart:int;
        var ypart:int;
        var md:Point;
        var mc:Point;
        var rd:Point;
        var ch:Sprite;

        public function CropTool(param1:Tuyitu, param2:Rectangle, param3:Object)
        {
            this.md = new Point();
            this.mc = new Point();
            this.rd = new Point();
            this.ed = param1;
            this.croprect = param2;
            this.options = param3;
            param1.addChild(this);
            param1.SetModal(this, false);
            if (param1.options.crop != null)
            {
                param1.options.crop.Lock();
            }
            if (param3.constraint != "none")
            {
                this.ax = param3.width;
                this.ay = param3.height;
            }
            this.x = param1.canvas.x + param1.canvas.masking.x;
            this.y = param1.canvas.y + param1.canvas.masking.y;
            this.tw = param1.canvas.masking.width;
            this.th = param1.canvas.masking.height;
            this.raster = new Sprite();
            this.raster.doubleClickEnabled = true;
            this.raster.addEventListener(MouseEvent.MOUSE_DOWN, this.RasterMouseDown, false, 1, true);
            this.raster.addEventListener(MouseEvent.MOUSE_OVER, this.HandlerMouseOver, false, 1, true);
            this.raster.addEventListener(MouseEvent.DOUBLE_CLICK, this.OK, false, 1, true);
            addChild(this.raster);
            this.topleft = new Sprite();
            this.AddCorner(this.topleft);
            this.topright = new Sprite();
            this.AddCorner(this.topright);
            this.bottomleft = new Sprite();
            this.AddCorner(this.bottomleft);
            this.bottomright = new Sprite();
            this.AddCorner(this.bottomright);
            stage.addEventListener(KeyboardEvent.KEY_UP, this.KeyUP, false, 0, true);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, this.KeyDown, false, 0, true);
            param1.modal.addEventListener(MouseEvent.MOUSE_OVER, this.ResetMouse, false, 0, true);
            param1.modal.addEventListener(MouseEvent.MOUSE_DOWN, this.ClickOutside, false, 0, true);
            this.Redraw();
            return;
        }// end function

        private function AddCorner(bottomleft:Sprite) : void
        {
            bottomleft.addEventListener(MouseEvent.MOUSE_DOWN, this.HandlerMouseDown, false, 1, true);
            bottomleft.addEventListener(MouseEvent.MOUSE_OVER, this.HandlerMouseOver, false, 1, true);
            bottomleft.graphics.beginFill(15658734);
            bottomleft.graphics.drawRect(0, 0, 9, 9);
            bottomleft.graphics.beginFill(4040436);
            bottomleft.graphics.drawRect(1, 1, 7, 7);
            addChild(bottomleft);
            return;
        }// end function

        private function ResetMouse(event:Event) : void
        {
            this.ed.cursor.Set(ToolType.None);
            return;
        }// end function

        private function KeyUP(event:KeyboardEvent) : void
        {
            if (event.keyCode == 13)
            {
                this.OK();
            }
            else if (event.keyCode == 27)
            {
                this.Cancel();
            }
            else if (event.keyCode == 16)
            {
                this.shifted = false;
            }
            return;
        }// end function

        private function KeyDown(event:KeyboardEvent) : void
        {
            if (event.keyCode == 16 && !this.shifted)
            {
                this.shifted = true;
            }
            return;
        }// end function

        public function ClickOutside(event:MouseEvent) : void
        {
            new ConfirmDialog(this.ed, U.RM("rm_apply_changes"), this.OK, this.Cancel);
            return;
        }// end function

        public function OK(event:Event = null) : void
        {
            this.croprect.x = Math.round(this.croprect.x / this.ed.canvas.zoomlevel - this.ed.canvas.document.x / this.ed.canvas.zoomlevel);
            this.croprect.y = Math.round(this.croprect.y / this.ed.canvas.zoomlevel - this.ed.canvas.document.y / this.ed.canvas.zoomlevel);
            this.croprect.width = Math.round(this.croprect.width / this.ed.canvas.zoomlevel);
            this.croprect.height = Math.round(this.croprect.height / this.ed.canvas.zoomlevel);
            this.ed.canvas.CropCanvas(this.croprect);
            if (this.options.constraint == "size" && this.ax != 0 && this.ay != 0)
            {
                this.ed.canvas.ResizeImage(this.ax, this.ay);
            }
            this.Close();
            return;
        }// end function

        public function Cancel(event:Event = null) : void
        {
            this.Close();
            return;
        }// end function

        public function Close() : void
        {
            this.ed.navigator.SetSelectionSize(0, 0);
            this.ed.modal.removeEventListener(MouseEvent.MOUSE_DOWN, this.ClickOutside, false);
            this.ed.modal.removeEventListener(MouseEvent.MOUSE_OVER, this.ResetMouse, false);
            stage.removeEventListener(KeyboardEvent.KEY_UP, this.KeyUP, false);
            stage.removeEventListener(KeyboardEvent.KEY_DOWN, this.KeyDown, false);
            if (this.ed.options.crop != null)
            {
                this.ed.options.crop.Unlock();
            }
            this.ed.removeChild(this);
            this.ed.RemoveModal();
            return;
        }// end function

        private function Redraw() : void
        {
            this.raster.graphics.clear();
            this.raster.graphics.beginFill(15658734, 0);
            this.raster.graphics.drawRect(this.croprect.left, this.croprect.top, this.croprect.width, this.croprect.height);
            this.raster.graphics.beginFill(15658734);
            this.raster.graphics.drawRect(this.croprect.left, this.croprect.top, this.croprect.width, 1);
            this.raster.graphics.drawRect(this.croprect.left, (this.croprect.bottom - 1), this.croprect.width, 1);
            this.raster.graphics.drawRect(this.croprect.left, this.croprect.top, 1, this.croprect.height);
            this.raster.graphics.drawRect((this.croprect.right - 1), this.croprect.top, 1, this.croprect.height);
            this.raster.graphics.endFill();
            this.xpart = Math.round(this.croprect.width / 3) - 1;
            this.ypart = Math.round(this.croprect.height / 3) - 1;
            this.raster.graphics.beginFill(15658734, 0.8);
            this.raster.graphics.drawRect(this.croprect.left + this.xpart, this.croprect.top, 1, this.croprect.height);
            this.raster.graphics.drawRect(this.croprect.left + this.xpart * 2, this.croprect.top, 1, this.croprect.height);
            this.raster.graphics.drawRect(this.croprect.left, this.croprect.top + this.ypart, this.croprect.width, 1);
            this.raster.graphics.drawRect(this.croprect.left, this.croprect.top + this.ypart * 2, this.croprect.width, 1);
            this.raster.graphics.endFill();
            this.topleft.x = this.croprect.left - 4;
            this.topleft.y = this.croprect.top - 4;
            this.topright.x = this.croprect.right - 5;
            this.topright.y = this.croprect.top - 4;
            this.bottomleft.x = this.croprect.left - 4;
            this.bottomleft.y = this.croprect.bottom - 5;
            this.bottomright.x = this.croprect.right - 5;
            this.bottomright.y = this.croprect.bottom - 5;
            this.ed.navigator.SetSelectionSize(this.croprect.width / this.ed.canvas.zoomlevel, this.croprect.height / this.ed.canvas.zoomlevel);
            return;
        }// end function

        private function HandlerMouseOver(event:MouseEvent) : void
        {
            switch(event.target as Sprite)
            {
                case this.topleft:
                case this.bottomright:
                {
                    this.ed.cursor.Set(ToolType.ResizeHeightWidth);
                    break;
                }
                case this.topright:
                case this.bottomleft:
                {
                    this.ed.cursor.Set(ToolType.ResizeWidthHeight);
                    break;
                }
                case this.raster:
                {
                    this.ed.cursor.Set(ToolType.MoveDrag);
                    break;
                }
                default:
                {
                    break;
                }
            }
            return;
        }// end function

        private function HandlerMouseDown(event:MouseEvent) : void
        {
            this.ed.cursor.freeze = true;
            this.ch = event.target as Sprite;
            switch(this.ch)
            {
                case this.bottomright:
                {
                    this.md = this.croprect.topLeft;
                    break;
                }
                case this.bottomleft:
                {
                    this.md.y = this.croprect.top;
                    this.md.x = this.croprect.right;
                    break;
                }
                case this.topright:
                {
                    this.md.y = this.croprect.bottom;
                    this.md.x = this.croprect.left;
                    break;
                }
                case this.topleft:
                {
                    this.md = this.croprect.bottomRight;
                    break;
                }
                default:
                {
                    break;
                }
            }
            stage.addEventListener(MouseEvent.MOUSE_MOVE, this.HandlerMouseMove, false, 1, true);
            stage.addEventListener(MouseEvent.MOUSE_UP, this.HandlerMouseUp, false, 1, true);
            return;
        }// end function

        private function HandlerMouseMove(event:MouseEvent) : void
        {
            this.mc.x = this.mouseX;
            this.mc.y = this.mouseY;
            if (this.mc.x < 0)
            {
                this.mc.x = 0;
            }
            else if (this.mc.x >= this.tw)
            {
                this.mc.x = this.tw - 1;
            }
            if (this.mc.y < 0)
            {
                this.mc.y = 0;
            }
            else if (this.mc.y >= this.th)
            {
                this.mc.y = this.th - 1;
            }
            this.croprect = Misc.CalculateRectangle(this.md, this.mc, this.ax, this.ay);
            this.Redraw();
            return;
        }// end function

        private function HandlerMouseUp(event:MouseEvent) : void
        {
            this.ed.cursor.freeze = false;
            if (event.target != this.ch)
            {
                this.ed.cursor.Set(ToolType.None);
            }
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.HandlerMouseMove, false);
            stage.removeEventListener(MouseEvent.MOUSE_UP, this.HandlerMouseUp, false);
            return;
        }// end function

        private function RasterMouseDown(event:MouseEvent) : void
        {
            this.ed.cursor.freeze = true;
            this.md.x = stage.mouseX;
            this.md.y = stage.mouseY;
            this.rd.x = this.croprect.x;
            this.rd.y = this.croprect.y;
            stage.addEventListener(MouseEvent.MOUSE_MOVE, this.RasterMouseMove, false);
            stage.addEventListener(MouseEvent.MOUSE_UP, this.RasterMouseUp, false);
            return;
        }// end function

        private function RasterMouseMove(event:MouseEvent) : void
        {
            this.croprect.x = this.rd.x - (this.md.x - stage.mouseX);
            this.croprect.y = this.rd.y - (this.md.y - stage.mouseY);
            if (this.croprect.x < 0)
            {
                this.croprect.x = 0;
            }
            else if (this.croprect.x + this.croprect.width > this.tw)
            {
                this.croprect.x = this.tw - this.croprect.width;
            }
            if (this.croprect.y < 0)
            {
                this.croprect.y = 0;
            }
            else if (this.croprect.y + this.croprect.height > this.th)
            {
                this.croprect.y = this.th - this.croprect.height;
            }
            this.Redraw();
            return;
        }// end function

        private function RasterMouseUp(event:MouseEvent) : void
        {
            this.ed.cursor.freeze = false;
            if (event.target != this.raster)
            {
                this.ed.cursor.Set(ToolType.None);
            }
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.RasterMouseMove, false);
            stage.removeEventListener(MouseEvent.MOUSE_UP, this.RasterMouseUp, false);
            return;
        }// end function

    }
}
